import jwt_decode from 'jwt-decode';

import { Logger } from '@/components/useLogger';

import { TokenState } from './enum';

export default class LocalInfo {
  static readonly Token = 'token';
  static readonly RoleId = 'ROLE_ID';

  static setItem(key: string, value: string) {
    try {
      localStorage.setItem(key, value);
    } catch (e) {
      Logger('localStorage setItem error:', e);
    }
  }

  static getItem(key: string): string | null {
    try {
      return localStorage.getItem(key);
    } catch (e) {
      Logger('localStorage getItem error:', e);
      return null;
    }
  }

  static removeItem(key: string) {
    try {
      localStorage.removeItem(key);
    } catch (e) {
      Logger('localStorage removeItem error:', e);
    }
  }

  static setToken(token: string) {
    this.setItem(this.Token, token);
  }

  static getToken(): string | null {
    return this.getItem(this.Token);
  }

  static setRoleId(roleId: number) {
    this.setItem(this.RoleId, roleId.toString());
  }

  static getRoleId(): number | undefined {
    const roleId = this.getItem(this.RoleId);
    return roleId ? parseInt(roleId, 10) : undefined;
  }

  static getDecodedToken(): any | undefined {
    try {
      const token = this.getToken();
      if (!token) {
        return undefined;
      }
      return jwt_decode(token);
    } catch (error) {
      Logger('decode token error:', error);
      return undefined;
    }
  }

  static getCurrentUserName(): string | undefined {
    try {
      const token = this.getDecodedToken();
      if (!token) {
        return undefined;
      }
      return token?.sub;
    } catch (error) {
      Logger('decode token error:', error);
      return undefined;
    }
  }

  static getTokenState(): TokenState | undefined {
    const token: { exp: number; [key: string]: any } = this.getDecodedToken();
    if (token) {
      const currentNumericDate = Math.round(Date.now() / 1000);
      if (currentNumericDate >= token.exp) return TokenState.EXPIRED;
      if (currentNumericDate + 15 * 60 >= token.exp) return TokenState.ABOUT_EXPIRED;
      return TokenState.VALID;
    }
    return undefined;
  }

  static getTokenExp(): number | undefined {
    const token: { exp: number; [key: string]: any } = this.getDecodedToken();
    return token?.exp;
  }

  static clear() {
    this.removeItem(this.Token);
    this.removeItem(this.RoleId);
  }
}
